/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2011  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.readers.filter;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.sosy_lab.common.configuration.Configuration;
import org.sosy_lab.common.configuration.InvalidConfigurationException;
import org.sosy_lab.common.configuration.Option;
import org.sosy_lab.common.configuration.Options;

@Options(prefix="reader.filter")
public class Filters implements java.util.Collection<Filter> {

  @Option(name="whitelist",
      description="A List of names that is to be matched. Matching is not case sensitive.")
  private List<String>             whitelist = null;

  @Option(name="sort",
      description="Sort output relations.")
  private boolean                  sort      = false;

  @Option(name="uniq",
      description="A filter that makes every tuple unique. This sorts implicitly.")
  private boolean                  uniq      = false;

  @Option(name="internal",
      description="Use only internal relations.")
  private boolean                  internal  = false;

  private final LinkedList<Filter> filters   = new LinkedList<Filter>();

  public Filters(Configuration config) throws InvalidConfigurationException {
    config.inject(this);

    // the order of the following is relevant
    // as tuples will get rearranged, changed and rewritten

    if (internal) {
      filters.add(new InternalRelations());
    }

    if (whitelist != null && whitelist.size() > 0) {
      filters.add(new WhitelistFilter(whitelist));
    }

    if (sort
        && !uniq) { // uniq sorts implicitly
      filters.add(new Sort());
    }

    if (uniq) {
      filters.add(new Uniq());
    }
  }

  @Override
  public int size() {
    return filters.size();
  }

  @Override
  public boolean isEmpty() {
    return filters.isEmpty();
  }

  @Override
  public boolean contains(Object filter) {
    return filters.contains(filter);
  }

  @Override
  public Iterator<Filter> iterator() {
    return filters.iterator();
  }

  @Override
  public Object[] toArray() {
    return filters.toArray();
  }

  @Override
  public <T> T[] toArray(T[] array) {
    return filters.<T>toArray(array);
  }

  @Override
  public boolean add(Filter filter) {
    return filters.add(filter);
  }

  @Override
  public boolean remove(Object filter) {
    return filters.remove(filter);
  }

  @Override
  public boolean containsAll(Collection<?> collection) {
    return filters.containsAll(collection);
  }

  @Override
  public boolean addAll(Collection<? extends Filter> collection) {
    return filters.addAll(collection);
  }

  @Override
  public boolean removeAll(Collection<?> collection) {
    return filters.removeAll(collection);
  }

  @Override
  public boolean retainAll(Collection<?> collection) {
    return filters.retainAll(collection);
  }

  @Override
  public void clear() {
    filters.clear();
  }

}
